import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
import {ElMessage} from 'element-plus'
import {staticRoutes,allAsyncRoutes,anyRoutes} from '@/router/routes'
import { reqLogin, reqLogout, reqUserInfo } from '@/api/acl/login';
// 引入路由器
import router from '@/router';
// 引入lodash
import _ from 'lodash'

// 定义过滤需要添加的动态路由
const findUserAsyncRoutes = (allAsyncRoutes,routes)=>{
  // 过滤一级路由
  return allAsyncRoutes.filter((item:any)=>{
    if(routes.includes(item.name)){
      if(item.children && item.children.length>0){
        // 过滤二级路由,递归再次调用函数
        item.children = findUserAsyncRoutes(item.children,routes)
      }
      return true
    }
  })
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore('userInfo', {

	state: (): UserInfoState => ({
    token: getToken() as string,
    name: '',
    avatar: '',
    menuRoutes: []
  }),

	actions: {
    // 登录
    async login (username: string, password: string) {
      try {
        let result = await reqLogin({username,password})
        // 登录之后需要做两件事:
        // 1.仓库存储token
        this.token = result.token
        // 2.本地化(持久化)存储token;
        setToken(result.token)
        return 'ok'
      } catch (error) {
        return Promise.reject(error)
      }
    },
    // 获取用户信息
    async getInfo () {
      try {
        let result = await reqUserInfo()
        // 需要让请求拦截器携带token(用户的唯一标识),获取用户信息
        this.name = result.name
        this.avatar = result.avatar
        // 此处为什么要使用深拷贝,因为需要将用户的路由与所有动态路由都进行比较,如果这一次比较后,没有深拷贝的话
        // 原动态路由的值就会被改变,所以需要使用一个不会改变原数据的对象来做这件事
        let userAsyncRoutes = findUserAsyncRoutes(_.cloneDeep(allAsyncRoutes),result.routes)
        this.setRoutes([...userAsyncRoutes,anyRoutes])
        // 修改仓库里面menuRoutes的属性值
        this.menuRoutes = [...staticRoutes,...userAsyncRoutes]
        return 'ok'
      } catch (error) {
        return Promise.reject(error)
      }
    },

    // 添加动态路由
    setRoutes(userRoutes:any){
      userRoutes.forEach((item:any)=>{
        router.addRoute(item)
      })
    },

    // 退出登录,记得还要清空动态路由的数据(因为拆分太麻烦,所以直接清空所有路由数据)
    async reset () {
      try {
        await reqLogout()
        // 删除本地化存储的token
        removeToken()
        // 清空仓库中的数据(用户信息)
        this.token = ''
        this.name = ''
        this.avatar = ''
        return 'ok'
      } catch (error) {
        return Promise.reject(error)
      }
    },

    // 清空路由的方法
    resetRoutes(){
      // 获取所有路由
      let allRoutes = router.getRoutes()
      // 遍历数组,清空数组中每一项路由
      allRoutes.forEach((item:any)=>{
        // removeRoute是通过路由的名称(即其name)来删除路由的
        router.removeRoute(item.name)
      })
      // 再次获取常量路由
      staticRoutes.forEach((item:any)=>{
        router.addRoute(item)
      })
    }
	},
});
